package com.qyer.lxp.common.framework.httpclient;

import com.qyer.lxp.common.framework.contants.ErrorMessageEnum;
import com.qyer.lxp.common.framework.contants.QyerContants;
import com.qyer.lxp.common.framework.exception.QyerException;
import com.qyer.lxp.common.framework.util.Md5Encrypt;
import com.qyer.lxp.common.framework.util.QyerConfig;
import com.qyer.lxp.common.framework.util.QyerUtils;
import com.qyer.lxp.common.framework.util.XMLReader;
import org.apache.commons.httpclient.DefaultHttpMethodRetryHandler;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.params.HttpMethodParams;
import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.http.*;
import org.apache.http.client.ClientProtocolException;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpUriRequest;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.util.EntityUtils;
import org.apache.log4j.Logger;
import org.springframework.util.Assert;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStreamWriter;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;

/**
 * Created by jiangping on 16/5/5.
 */
public class HttpClientUtil {

    static final Logger logger = Logger.getLogger(HttpClientUtil.class);

    private static String url = "http://api.lixing.biz/service?method=";
    private static String user = "C100000362";
    private static String key = "4a071cd838d7fbeec1225dd7d125be3a";

    public static String requestPost(String methodName,String param) throws Exception {
        HttpClient httpclient = HttpClientPoolCache.getInstance().getHttpClient();
        url = QyerConfig.getInstance().getString(QyerContants.QYER_CONNECTION_URL,"http://api.lixing.biz/service?method=");
        key = QyerConfig.getInstance().getString(QyerContants.QYER_CONNECTION_KEY,"C100000362");
        user = QyerConfig.getInstance().getString(QyerContants.QYER_CONNECTION_USER,"4a071cd838d7fbeec1225dd7d125be3a");
        String result = "";

        try {
            HttpPost httppost = new HttpPost(url+methodName);
            List<NameValuePair> nvps = new ArrayList<NameValuePair>();
            String sign = Md5Encrypt.md5(StringUtils.isNotBlank(param)?"para" + param + key:key);
            if(StringUtils.isNotBlank(param)) {
                nvps.add(new BasicNameValuePair("para", param));
            }
            nvps.add(new BasicNameValuePair("user", user));
            nvps.add(new BasicNameValuePair("sign", sign));
            httppost.setEntity(new UrlEncodedFormEntity(nvps,"UTF-8"));
            long timeIn = System.currentTimeMillis();
            HttpResponse response = httpclient.execute(httppost);
            long timeOut =System.currentTimeMillis();
            logger.info("调用力行"+methodName+"接口耗时:"+(timeOut-timeIn)+"ms");
            int statusCode = response.getStatusLine().getStatusCode();
            if (statusCode == HttpStatus.SC_OK) {
                HttpEntity resEntity = response.getEntity();
                result = EntityUtils.toString(resEntity);
                if(QyerUtils.isNotEmpty(result)){
                    XMLReader.getInstance().parse(result);
                    if(!XMLReader.getInstance().isExistNote("payload"))
                    {
                        String statusCodes = XMLReader.getInstance().getElements("status-code");
                        if("200".equals(statusCodes)){
                            return "";
                        }else {
                            throw new QyerException(statusCodes);
                        }
                    }else if(XMLReader.getInstance().isExistNote("message")){
                        throw new Exception(XMLReader.getInstance().getElements("message"));
                    }else {

                    }
                }
            } else {
                logger.error(
                        "调用远程服务器出错"
                                + response);
            }

        } catch (Exception e) {
            logger.info("请求参数是:"+param);
            logger.info("返回参数是:"+result);
            logger.error("通过HTTP方式调用第三方接口异常", e);
            throw new Exception(e);
        } finally {
            try {
                httpclient.getConnectionManager().shutdown();
            } catch (Exception ignore) {
            }
        }
        return  result;
    }

    /**
     * 处理力行返回没有根结点的xml,将根点加上,
     * 并加上xml头信息,方便将xml序列化成java对象
     * @param xml   符合xml格式的字符串
     * @param elementRoot   需要加入的根结点
     * @return  返回加上根结点后的xml
     */
    public static String removeExtraHeader(String xml,String elementRoot) throws Exception {
        if(QyerUtils.isEmpty(xml)){
            return "";
        }
        /*if(!(xml.contains("<payload>")))
        {

            return xml;
        }*/
        Assert.hasText(elementRoot,"elementRoot参数为空!");
        StringBuilder root = new StringBuilder();
        StringBuilder httpclientResultXml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        String bodyXml = removeHeader(xml);
        elementRoot = convertToName(elementRoot);
        root.append("<").append(elementRoot).append(">")
            .append(bodyXml).append("</").append(elementRoot)
            .append(">");
        return httpclientResultXml.append(root.toString()).toString();
    }

    /**
     * 处理正常的xml,将不需要的头结点去掉,只要payload包含的内容,
     * 并加上xml头信息
     * @param xml   符合xml格式的字符串
     * @return  返回payload包含的内容
     */
    public static String removeNormalHeader(String xml) throws Exception {
        if(QyerUtils.isEmpty(xml)){
            return "";
        }
        /*if(!(xml.contains("<payload>")))
        {
            return xml;
        }*/
        StringBuilder httpclientResultXml = new StringBuilder("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
        return httpclientResultXml.append(removeHeader(xml)).toString();
    }

    /**
     * 去掉xml头部信息,只要payload包含的内容
     * @param xml   符合xml格式的字符串
     * @return 返回payload包含的内容,不包含xml头信息
     */
    public static String removeHeader(String xml) throws Exception {
        if(QyerUtils.isEmpty(xml)){
            return "";
        }
        if(!(xml.contains("<payload>")))
        {
            return xml;
        }
        int payloadStart = xml.indexOf("<payload>");
        int payloadEnd =xml.indexOf("</payload>");
        String xml1 = xml.substring(payloadStart+9,payloadEnd);
        return xml1;
    }

    /**
     * 将传入的根结点转换成力行xml格式的结点
     * @param elementName
     * @return
     */
    public static String convertToName(String elementName){
        Assert.hasText(elementName,"elementName为空!");
        StringBuilder elementRootName = new StringBuilder();
        char[] chars = elementName.toCharArray();
        int j = 0;
        int m = 0;
        byte[] bytes = new byte[chars.length >> 1];
        String mid = "";
        for (int i = 0; i < chars.length; i++) {
            if (chars[i] >= 65 && chars[i] <= 90) {
                j++;
                bytes[m] = (byte) i;
                m++;
            }
        }

        if(j == 0){
            return elementName;
        }

        if(j == 1){
            return elementName.toLowerCase();
        }
        for (int n = 0; n < m; n++) {
            if (n == m - 1) {
                mid = elementName.substring(bytes[n]);
            } else {
                mid = elementName.substring(bytes[n], bytes[n + 1]);
            }
            elementRootName.append(mid);
            if (n != m - 1) {
                elementRootName.append("-");
            }
        }
        return elementRootName.toString().toLowerCase();
    }

    public static String postBody(String urlPath, String json) throws Exception {
        try{
            // Configure and open a connection to the site you will send the request
            URL url = new URL(urlPath);
            HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
            // 设置doOutput属性为true表示将使用此urlConnection写入数据
            urlConnection.setDoOutput(true);
            // 定义待写入数据的内容类型，我们设置为application/x-www-form-urlencoded类型
            urlConnection.setRequestProperty("content-type", "application/json");
            // 得到请求的输出流对象
            OutputStreamWriter out = new OutputStreamWriter(urlConnection.getOutputStream());
            // 把数据写入请求的Body
            out.write(json);
            out.flush();
            out.close();

            // 从服务器读取响应
            InputStream inputStream = urlConnection.getInputStream();
            String encoding = urlConnection.getContentEncoding();
            String body = IOUtils.toString(inputStream, encoding);
            if(urlConnection.getResponseCode()==200){
                return body;
            }else{
                throw new Exception(body);
            }
        }catch(IOException e){
            e.getMessage();
        }
        return null;
    }

    /**
     * 将返回的json对象加上response信息
     * @param nameSpace
     * @param data
     * @return
     */
    public static String addHeaderTemplete(String nameSpace,String data){
        if(QyerUtils.isEmpty(nameSpace)){
            return "";
        }
        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append("{\"namespace\":\"")
                .append(nameSpace)
                .append("\",\"status\":200,\"msg\":\"OK\",\"data\":")
                .append(QyerUtils.isEmpty(data)?"":data)
                .append("}");
        return stringBuilder.toString();
    }

    public static void main(String[] args) {

        String xml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><product-code-search-request><update-date-start>2016-05-01</update-date-start><update-date-end>2016-05-30</update-date-end><start>1</start><end>10</end></product-code-search-request>";
        try {
            String result = HttpClientUtil.requestPost("getUpdateProductInfo",xml);
            System.out.println(result);
            System.out.println(HttpClientUtil.convertToName("httpclient"));
        }catch (Exception e){
            e.printStackTrace();
        }

    }
}
